use std::{cell::UnsafeCell, mem::MaybeUninit, ops::Deref};

#[repr(transparent)]
pub struct UninitCell<T>(pub UnsafeCell<MaybeUninit<T>>);

unsafe impl<T: Send> Send for UninitCell<T> {}
unsafe impl<T: Sync> Sync for UninitCell<T> {}

impl<T> UninitCell<T> {

    pub const fn empty() -> Self {
        Self(UnsafeCell::new(MaybeUninit::uninit()))
    }

    pub unsafe fn init(&self, value: T) {
        (&mut *self.0.get()).write(value);
    }

    pub const fn as_ref(&self) -> &T {
        unsafe { (&*self.0.get()).assume_init_ref() }
    }
}

impl <T> Deref for UninitCell<T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        self.as_ref()
    }
}


